/*  Create simple Mask Generation Function for IEEE P1363 standard  */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern void sha_memory();
int MGF_Hash();

/*  MGF-Hash

	As described in section 13.2.1 of 21 Sept. 1997 P1363 draft.  
	Assumes 32 bit inputs, no size error returned.
	This version calls Jim Gilogly's implementation of SHA-1.
	
	Input:
			BYTE string Z of length zLen
			pointer to output area (BYTE) mask
			number of bytes desired in output oLen
	Output:
			mask filled with oLen bytes of garbage,
			returns 0 for no error,
			returns 1 if not enough memory available
*/

int MGF_Hash( Z, zLen, mask, oLen)
unsigned char *Z, *mask;
unsigned long zLen, oLen;
{
	unsigned char *catspace, *catpoint;
	int           tbyte, counter;
	unsigned long cThreshold = oLen/20;
	unsigned long  *M, temp[5];
	
	M = (unsigned long*) mask;

/*  establish enough memory space to do the hashing with counter  */

	catspace = malloc( zLen + 4);
	if ( !catspace) return(1);
	memcpy ( catspace, Z, zLen);
	catpoint = catspace + zLen;

/*  create main block of mask data  */

	for ( counter = 0; counter < cThreshold; counter++)
	{
		*catpoint = (counter >> 24) & 0xFF;
		*(catpoint+1) = (counter >> 16) & 0xFF;
		*(catpoint+2) = (counter >> 8) & 0xFF;
		*(catpoint+3) = counter & 0xFF;
		sha_memory( catspace, zLen+4, M);
		M += 5;
	}

/*  finish up any uneven multiples of a single hash step  */

	if ( tbyte = oLen % 20)
	{
		*catpoint = (counter >> 24) & 0xFF;
		*(catpoint+1) = (counter >> 16) & 0xFF;
		*(catpoint+2) = (counter >> 8) & 0xFF;
		*(catpoint+3) = counter & 0xFF;
		sha_memory( catspace, zLen+4, temp);
		memcpy( M, temp, tbyte);
	}
	free ( catspace);
	return (0);
}
